
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;
using System.Runtime.Serialization;
using System.Xml;
using Swaf.Call;
using Swaf.Container;

namespace Swaf.Security
{
	/// <summary>
	/// The SecurityPrincipal class inherits from SecurityPrincipalBase and provides 
	/// the full security implementation exposed via the SecurityFeature feature file.  
	/// This class implements the getPrivilege method and does not override any of the 
	/// functions in the base class.  The getPrivilege method calls the get method of the 
	/// resourceSets property to get the effective privilege of the requested resource.
	/// </summary>
	[Serializable]
	public class SecurityPrincipal : SecurityPrincipalBase	
	{
		protected IDictionary m_cache = null;

		/// <summary>
		/// Constructor for instancing a default security principal from code
		/// </summary>
		/// <param name="UserName">The name of the user associated with this principal</param>
		/// <param name="additionalInfo">INameAddressSupport instance containing application 
		/// specific information about the principal</param>
		/// <param name="rolesCall">ICall instance used to retrieve the roles for a principal.</param>
		public SecurityPrincipal(string UserName, INameAddressSupport additionalInfo, ICall rolesCall) : base(UserName, additionalInfo, rolesCall)
		{
			m_cache = new ThreadSafeHashtable();
		}
		/// <summary>
		/// Constructor used by the configuration system or to deserialize a serialized principal from an Xml node.
		/// </summary>
		/// <param name="ele">XmlNode containing information about the principal</param>
		public SecurityPrincipal(XmlElement ele) : base(ele)
		{
			m_cache = new ThreadSafeHashtable();
		}
		
		/// <summary>
		/// Constructor used by the system during binary deserialization
		/// </summary>
		/// <param name="info"></param>
		/// <param name="context"></param>
		public SecurityPrincipal(System.Runtime.Serialization.SerializationInfo info, StreamingContext context) : base(info, context)
		{
			m_cache = new ThreadSafeHashtable();
		}

		#region ISecurityPrincipal Members

		/// <summary>
		/// Implementation of abstract getPrivilige method from base class.  This implementation
		/// returns the privilege as defined in the requested ResourceSet.  If no privilege is
		/// found, Privileges.None is returned.
		/// </summary>
		/// <param name="resourceName">Fully qualified name of the requested resource (ResourceSet.Resource)</param>
		/// <returns></returns>
		public override Privileges getPrivilege(string resourceName)
		{
			return getPrivilege(resourceName, true);
		}

		public override Privileges getPrivilege(string resourceName, bool useDefaultIfNeeded)
		{
			Privileges thisPrivilege = Privileges.None;

			if (m_cache.Contains(resourceName))
				thisPrivilege = (Privileges)m_cache[resourceName];
			else
			{
				thisPrivilege = (Privileges)this.m_resourceSets.get(resourceName, useDefaultIfNeeded);
				m_cache.Add(resourceName, thisPrivilege);
			}

			return thisPrivilege;
		}

		#endregion
	}
}
